package nl.zuiderfestival.raydance.view;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EtchedBorder;

import nl.zuiderfestival.raydance.control.RayDanceListener;
import nl.zuiderfestival.raydance.model.RayDance;
import nl.zuiderfestival.raydance.model.RayEvent;
import nl.zuiderfestival.raydance.model.RayEventType;
import nl.zuiderfestival.raydance.model.zones.Zone;

public class ZonePanel extends JPanel implements Observer {

	private static final long serialVersionUID = 1L;
	
	public static final String CHANGE_SELECTION = "CHANGE_SELECTION";
	public static final String ADD = "ADD";
	public static final String REMOVE = "REMOVE";
	public static final String CHANGE_WIDTH = "CHANGE_WIDTH";
	public static final String CHANGE_HEIGHT = "CHANGE_HEIGHT";
	public static final String CHANGE_X = "CHANGE_X";
	public static final String CHANGE_Y = "CHANGE_Y"; 

	private JComboBox<Zone> comboBox;
	private JButton addButton;
	private JButton removeButton;
	private JLabel widthDisplay;
	private JLabel heightDisplay;
	private JLabel xDisplay;
	private JLabel yDisplay;
	
	public ZonePanel() {
		super(new GridBagLayout());

		Dimension size = getPreferredSize();
		size.height = 150;
		setPreferredSize(size);
		
		createContent();
		
		setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
	}

	@SuppressWarnings("unchecked")
	public void update(Observable o, Object arg) {
		if (o instanceof RayDance && arg instanceof RayEvent) {
			RayEvent event = (RayEvent) arg;
			
			if (event.getType() == RayEventType.INIT) {
				Set<Zone> initZones = (Set<Zone>) event.getData();
				for (Zone zone : initZones) {
					comboBox.addItem(zone);
					zone.addObserver(this);
				}
			} else if (event.getType() == RayEventType.ZONEADDED) {
				comboBox.addItem((Zone)event.getData());
				((Zone)event.getData()).addObserver(this);
			} else if (event.getType() == RayEventType.ZONEREMOVED) {
				comboBox.removeItem((Zone)event.getData());
				((Zone)event.getData()).deleteObserver(this);
			} else if (event.getType() == RayEventType.SELECTIONCHANGED) {
				Zone zone = (Zone)event.getData();
				if (zone != null) {
					comboBox.setSelectedItem(zone);
					updateLabels(zone);
				} else {
					comboBox.setSelectedIndex(-1);
					widthDisplay.setText("-");
					heightDisplay.setText("-");
					xDisplay.setText("-");
					yDisplay.setText("-");
				}
			}
		} else if (o instanceof Zone) {
			Zone z = (Zone) o;
			if (z.equals(comboBox.getSelectedItem())) {
				updateLabels(z);
			}
		}
	}

	private void updateLabels(Zone zone) {
		widthDisplay.setText(""+zone.getSize().width);
		heightDisplay.setText(""+zone.getSize().height);
		xDisplay.setText(""+zone.getLocation().x);
		yDisplay.setText(""+zone.getLocation().y);
	}

	public Zone getSelectedZone() {
		return (Zone)comboBox.getSelectedItem();
	}

	public void addRayDanceListener(RayDanceListener l) {
		comboBox.addActionListener(l);
		addButton.addActionListener(l);
		removeButton.addActionListener(l);
	}

	@SuppressWarnings("unchecked")
	private void createContent() {
	    GridBagConstraints c = new GridBagConstraints();
	    c.fill = GridBagConstraints.HORIZONTAL;
		c.insets = new Insets(2,2,2,2);
	    
		comboBox = (JComboBox<Zone>) add(new JComboBox<Zone>(), c, 0, 1);
		comboBox.setActionCommand(CHANGE_SELECTION);
		//comboBox.setRenderer(new LabelRenderer());
	    
		addButton    = (JButton) add(createButton("Add zone", ADD),       c, 0, 0);
		removeButton = (JButton) add(createButton("Remove zone", REMOVE), c, 1, 0);
		
		add(new JLabel("x: "), c, 3, 1);
		add(new JLabel("y: "), c, 3, 2);
		xDisplay = (JLabel) add(new JLabel(), c, 4, 1);
		yDisplay = (JLabel) add(new JLabel(), c, 4, 2);

		add(new JLabel("width: "), c, 5, 1);
		add(new JLabel("height: "), c, 5, 2);
		widthDisplay = (JLabel) add(new JLabel(), c, 6, 1);
		heightDisplay = (JLabel) add(new JLabel(), c, 6, 2);
	}
	
	private Component add(Component component, GridBagConstraints c, int gridx, int gridy) {
		c.gridx = gridx;
		c.gridy = gridy;
		add(component, c);
		return component;
	}

	private JButton createButton(String label, String actionCommand) {
		JButton button = new JButton(label);
		button.setActionCommand(actionCommand);
		return button;
	}
}
